package com.example.yupao_project.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.yupao_project.component.*;
import com.example.yupao_project.entity.User;
import com.example.yupao_project.entity.param.LoginRe;
import com.example.yupao_project.entity.param.UserInfoVo;
import com.example.yupao_project.exception.BusinessException;
import com.example.yupao_project.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author: 杰
 * @date: 2024/4/30 17:38
 */
@RequestMapping("/user")
@RestController
@Slf4j
public class UserController {
    @Resource
    private UserService userService;

    @Autowired
    private SessionUtil sessionUtil;

    @Autowired
    private HandlingPrivacy handlingPrivacy;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 用户注册功能
     *
     * @param userInfoVo 注册信息
     * @return ResultUtils
     */
    @RequestMapping("/register")
    public BaseResponse<String> register(UserInfoVo userInfoVo) {
        return ResultUtils.success(userService.register(userInfoVo));
    }

    /**
     * 登录功能
     *
     * @param loginRe 登录信息
     * @param request 网络请求
     * @return ResultUtils
     */
    @PostMapping("/login")
    public BaseResponse<String> login(@RequestBody LoginRe loginRe, HttpServletRequest request) {
        HttpSession session = request.getSession(true);
        return ResultUtils.success(userService.login(loginRe.getUserAccount(), loginRe.getUserPassword(), session));
    }

    /**
     * 查询
     *
     * @param username 用户名
     * @param request  request请求
     * @return ResultUtils
     */
    @GetMapping("/searchByName")
    public BaseResponse<List<User>> searchUsers(String username, HttpServletRequest request) {
        //校验数据
        if (!StringUtils.hasLength(username))
            throw new BusinessException(ErrorCode.NULL_ERROR, "未输入用户名");
        //获取当前用户并判断是否为管理员
        User user = (User) sessionUtil.getSession(request);
        if (user == null || user.getUserRole() != 1)
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限");
        //查询数据
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("username", username);
        List<User> userList = userService.list(queryWrapper);
        for (User curUser : userList) {
            handlingPrivacy.handlingPrivacy(curUser);
        }
        return ResultUtils.success(userList);
    }

    /**
     * 删除操作
     *
     * @param id      删除id
     * @param request request请求
     * @return ResultUtils
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(long id, HttpServletRequest request) {
        //获取当前用户并判断是否为管理员
        User user = (User) sessionUtil.getSession(request);
        if (user == null || user.getUserRole() != 1)
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限");
        //查询数据
        if (id <= 0)
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        return ResultUtils.success(userService.removeById(id));
    }

    /**
     * 通过标签搜索用户
     *
     * @param tagList 标签
     * @return ResultUtils
     */
    @GetMapping("/searchByTags")
    public BaseResponse<List<User>> searchUserByTags(@RequestParam(value = "tagNameList") List<String> tagList) {
        return ResultUtils.success(userService.searchUserByTags(tagList));
    }

    /**
     * 获取当前用户session
     *
     * @param httpServletRequest request
     * @return ResultUtils
     */
    @GetMapping("/getCurSession")
    public BaseResponse<User> getCurSession(HttpServletRequest httpServletRequest) {
        User user = (User) sessionUtil.getSession(httpServletRequest);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        }
        return ResultUtils.success(user);
    }

    /**
     * 更新用户信息
     *
     * @param user 用户信息
     * @return ResultUtils
     */
    @PostMapping("/updateUserInfo")
    public BaseResponse<Boolean> updateUserInfo(@RequestBody User user, HttpServletRequest request) {
        User loginUser = (User) sessionUtil.getSession(request);
        if (loginUser == null || loginUser.getId() < 0)
            throw new BusinessException(ErrorCode.NOT_LOGIN);
        return ResultUtils.success(userService.updateUserInfo(user, request));
    }

    /**
     * 推荐数据库中用户
     *
     * @return ResultUtils
     */
    @GetMapping("/recommend")
    public BaseResponse<Page<User>> recommend(long pageSize, long pageNum, HttpServletRequest request) {
        User curUser = (User) sessionUtil.getSession(request);
        if (curUser == null) throw new BusinessException(ErrorCode.NOT_LOGIN);
        String redisKey = String.format("yupao_project:user:recommend:%s", curUser.getId());
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        //读取缓存内容
        Page<User> userPage = (Page<User>) valueOperations.get(redisKey);
        if (userPage != null) return ResultUtils.success(userPage);
        //如果userPage为空，说明缓存为空，这时候就要从数据库中进行查询
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Page<User> pageList = userService.page(new Page<>(pageNum, pageSize), queryWrapper);
        //将查询的内容存入redis
        try {
            valueOperations.set(redisKey, pageList, 60, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.info("存入缓存失败");
        }
        return ResultUtils.success(pageList);
    }

    @GetMapping("/match")
    public BaseResponse<List<User>> matchUsers(long num, HttpServletRequest request) {
        return ResultUtils.success(userService.matchUsers(num, request));
    }
}
